#! _*_ coding: utf8 _*_
import datetime
import json

from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.core import serializers
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from rest_framework.decorators import api_view

from accounts.util import create_user, params_of_request
from school.models import School
from student.models import Student, STextBook, SClass
from student.serializers import StudentSerializer, SClassSerializer
from student.student_util import student_of_uid
from teacher.utils import schools_of_teacher, create_class
from tools.err import ErrorDoesNotExist, RoingException
from .models import Teacher
from .serializers import TeacherSeri


# Create your views here.
@login_required
def teacher(request):
    response = {}

    schoolid = request.GET.get('school', 0)
    school = School.objects.filter(pk=schoolid)
    if not school:
        return JsonResponse({'msg': 'error'})
    teachers = [User.objects.get(pk=t.me) for t in school.teacher]
    response['teachers'] = json.loads(serializers.serialize("json", teachers))
    return JsonResponse(response)


@login_required
def students(request):
    teacher_id = request.GET.get('teacher_id', 0)
    teacher = {}
    textbooks = []
    try:
        teacher = Teacher.objects.get(pk=teacher_id)
        textbooks = STextBook.objects.all()
    except Exception as e:
        pass

    school_id = request.GET.get('school_id', None)
    school = None
    try:
        school = School.objects.get(pk=school_id)
    except Exception as e:
        pass
    if request.user != teacher.me and school and school.owner != request.user:
        return HttpResponse(status=403, content=u'没有权限')
    return render(request, 'teacher-students.html',
                              {'user': request.user, 'teacher': teacher, 'textbooks': textbooks})


def c_teacher(request):
    try:
        teacher = Teacher.objects.get(me=request.user)
        return JsonResponse(TeacherSeri(teacher).data, safe=False)
    except Teacher.DoesNotExist as e:
        return HttpResponse(status=601)
    return HttpResponse(status=-1)


def c_teacher_detail(request):
    params = params_of_request(request)
    tid = params.get('tid', 0)
    try:
        teacher = Teacher.objects.get(pk=tid)
        return JsonResponse(TeacherSeri(teacher, context={'excludes': ['teacher_schools']}).data, safe=False)
    except Teacher.DoesNotExist as e:
        return JsonResponse({'message': str(e)})


def c_students(request):
    try:
        teacher = Teacher.objects.get(me=request.user)
        return JsonResponse({'students': StudentSerializer(teacher.students.all(), many=True).data}, safe=False)
    except Exception as e:
        return JsonResponse({'students': []})


def add_teacher(request):
    if request.method == 'GET':
        return render(request, 'teacher-add.html',
                      {'user': request.user, 'school_id': request.GET.get('school_id', None)})
    else:
        user = create_user(None, request.POST, {})
        if not user:
            return JsonResponse({'msg': 'error'})

        try:
            teacher = Teacher.objects.get(me=user)
        except Exception as e:
            teacher = Teacher.objects.create(me=user)

        school_id = request.POST.get('school_id', None)
        try:
            school = School.objects.get(pk=school_id)
            school.teachers.add(teacher)
            teacher.save()
            school.save()
            return HttpResponseRedirect('/teacher/add?school_id=' + str(school_id))
        except Exception as e:
            return JsonResponse({'msg': str(e)})


def add_student(request):
    teacher_id = request.GET.get('teacher_id', 0)
    student_id = request.GET.get('student_id', 0)
    teacher = Teacher.objects.get(pk=teacher_id)
    students = Student.objects.filter(student_teachers=None)
    if request.user != teacher.me:
        return HttpResponse(status=403, content=u"只有" + teacher.me.first_name + u"老师才能给自己添加学生")
    if not student_id:
        return render(request, 'teacher-students-add.html',
                                  {'user': request.user, 'teacher': teacher, 'students': students})
    else:
        student = Student.objects.get(pk=student_id)
        teacher.students.add(student)
        teacher.save()
        return JsonResponse({'msg': 'success'})


@api_view(['POST', 'GET'])
def c_remove_students(request):
    try:
        students_json = request.data.get('students', [])
        teacher = Teacher.objects.get(me=request.user)

        schools = teacher.teacher_schools.all()
        if len(schools) == 0:
            school = None
        else:
            school = schools[0]

        # deleted_students = []
        for student_json in students_json:
            pk = student_json.get('pk', None)
            if pk:
                try:
                    student = Student.objects.get(pk=int(pk))
                    for c in student.classes.all():
                        c.delete()

                    if school:
                        school.students.remove(student)
                except Exception as e:
                    raise RoingException(message=str(e), code=603)
        return JsonResponse({'students': students_json})
    except Teacher.DoesNotExist as e:
        raise RoingException(message=str(e), code=ErrorDoesNotExist)
    except Exception as e:
        raise RoingException(message=str(e), code=603)


@api_view(['GET', 'POST'])
def c_update_teacher(request):
    try:
        teacher = Teacher.objects.get(me=request.user)
        json_teacher = request.data.get('teacher', {})
        seri = TeacherSeri(teacher, data=json_teacher)
        seri.is_valid()
        seri.save()
        return JsonResponse({'teacher': seri.data}, safe=False)
    except Teacher.DoesNotExist as e:
        raise RoingException(message=str(e), code=ErrorDoesNotExist)
    except Exception as e:
        raise RoingException(message=str(e), code=603)


def add_class(request):
    if request.method == 'GET':
        teacher_id = request.GET.get('teacher_id', 0)
        teacher = Teacher.objects.get(pk=teacher_id)
        return render(request, 'teacher-class-add.html', {'teacher': teacher})
    else:
        teacher_id = request.POST.get('teacher_id', 0)
        student_id = request.POST.get('student_id', 0)
        weekday = request.POST.get('weekday', 0)
        begin_str = request.POST.get('begin', '')
        duration = request.POST.get('duration', 0)

        try:
            begin = datetime.datetime.strptime(begin_str, '%H:%M')
            duration_delta = datetime.timedelta(0, float(duration) * 60)
            clz = SClass.objects.create(weekday=int(weekday), begin=begin, duration=duration_delta)
            clz.save()

            student = Student.objects.get(pk=student_id)
            student.classes.add(clz)
            student.save()
            return HttpResponse({'msg': 'success', 'code': 0})
        except Exception as e:
            return JsonResponse({'msg': str(e), 'code': -1})


def c_add_class(request):
    try:
        # 先保证老师有学校
        teacher = Teacher.objects.get(me=request.user)
        schools = schools_of_teacher(teacher)
        school = schools[0]

        # 保证学生已录入
        clzs = json.loads(request.body).get('classes', [])
        if not teacher.teacher_classes:
            teacher.teacher_classes = []

        for clz in clzs:
            obj_clz = create_class(clz)
            obj_clz.teacher = teacher
            obj_clz.save()
            for s in obj_clz.class_students.all():
                school.students.add(s)

        teacher.save()
        return JsonResponse(TeacherSeri(teacher).data, safe=False)
    except User.DoesNotExist as e:
        return HttpResponse(status=ErrorDoesNotExist)
    except Exception as e:
        pass
    return HttpResponse(status=500, content='error')


def c_delete_class(request):
    try:
        params = json.loads(request.body)
        clz_id = params.get('pk', None)
        clz = SClass.objects.get(pk=int(clz_id))
        clz.delete()
    except SClass.DoesNotExist as e:
        return HttpResponse(status=601, content=str(e))
    except Exception as e:
        return HttpResponse(status=-1)
    return JsonResponse({'msg': 'success'})


def c_update_class(request):
    try:
        params = json.loads(request.body)
        classes = params.get('classes', [])
        for clz in classes:
            clz_id = clz.get('pk', None)

            c = SClass.objects.get(pk=int(clz_id))
            try:
                t = c.teacher
            except Exception as e:
                try:
                    c.teacher = Teacher.objects.get(me=request.user)
                except Exception as e:
                    pass

            seri = SClassSerializer(c, data=clz, partial=True)
            seri.is_valid()
            seri.save()

            return JsonResponse(seri.data, safe=False)
    except Exception as e:
        return HttpResponse(status=601, content=str(e))


def c_teacher_classes(request):
    try:
        teacher = Teacher.objects.get(me=request.user)
        return JsonResponse(
            {'classes': SClassSerializer(teacher.teacher_classes, context={'excludes': []}, many=True).data},
            safe=False)
    except Teacher.DoesNotExist as e:
        return HttpResponse(status=404)


def teacher_classes(request):
    teacher_id = request.GET.get('teacher_id', None)
    school_id = request.GET.get('school_id', None)

    teacher = None
    school = None
    try:
        if not teacher_id:
            teacher = Teacher.objects.get(me=request.user)
        else:
            teacher = Teacher.objects.get(pk=teacher_id)
        school = School.objects.get(pk=school_id)
    except Exception as e:
        pass

    teacher.teacher_schools.all()
    if request.user != teacher.me and school and school.owner != request.user:
        return HttpResponse(status=403)

    classes = []
    try:
        students = teacher.students.all()
        for s in students:
            sclasses = s.classes.all()
            sclasses_json = json.loads(serializers.serialize("json", sclasses))
            for scj in sclasses_json:
                scj['fields']['name'] = s.me.last_name + s.me.first_name
                scj['fields']['student'] = s.pk
            classes.extend(sclasses_json)
    except Exception as e:
        return JsonResponse({'msg': 'error'})
    finally:
        return JsonResponse({'classes': classes})
